package com.atguigu.eduservice.service.impl;

import com.atguigu.commonutils.R;
import com.atguigu.commonutils.ResultCode;
import com.atguigu.eduservice.entity.EduCourse;
import com.atguigu.eduservice.entity.EduCourseDescription;
import com.atguigu.eduservice.entity.EduTeacher;
import com.atguigu.eduservice.entity.chapter.ChapterVo;
import com.atguigu.eduservice.entity.frontvo.CourseFrontVo;
import com.atguigu.eduservice.entity.frontvo.CourseWebVo;
import com.atguigu.eduservice.entity.vo.CourseInfoVo;
import com.atguigu.eduservice.entity.vo.CoursePublishVo;
import com.atguigu.eduservice.entity.vo.CourseQuery;
import com.atguigu.eduservice.mapper.EduCourseDescriptionMapper;
import com.atguigu.eduservice.mapper.EduCourseMapper;
import com.atguigu.eduservice.service.EduChapterService;
import com.atguigu.eduservice.service.EduCourseDescriptionService;
import com.atguigu.eduservice.service.EduCourseService;
import com.atguigu.eduservice.service.EduVideoService;
import com.atguigu.servicebase.exceptionhandler.CustomizeException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mysql.cj.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author hwt
 * @since 2022-08-23
 */
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {
    @Resource
    EduCourseDescriptionMapper courseDescriptionMapper;

    @Resource
    EduVideoService eduVideoService;
    @Resource
    EduChapterService chapterService;
    @Resource
    EduCourseDescriptionService courseDescriptionService;


    @Transactional  // 标记事务方法，出现异常会进行事务回滚
    @Override
    public R savaCourseInfo(CourseInfoVo infoVo) {

        // 这里需要将课程信息、课程简介 分别储存到两张表中

        // 添加到课程基础信息表
        // 我们可以使用 spring 提供的 bean 工具类，将一个对象，复制到另外一个对象中去，有的属性才会复制，没有就不会复制
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(infoVo, eduCourse);

        // 我们可以使用 baseMapper 来进行存储，也可以使用 this
        int insert = baseMapper.insert(eduCourse);

        System.out.println("================================="+eduCourse.getId());

        if (insert == 0) throw new CustomizeException(ResultCode.ERROR.getValue(), "添加失败，请稍后重试");


        // 添加到课程描述表
        EduCourseDescription courseDescription = new EduCourseDescription();
        courseDescription.setDescription(infoVo.getDescription());

        // 设置相同主键 id
        courseDescription.setId(eduCourse.getId());

        insert = courseDescriptionMapper.insert(courseDescription);

        if (insert == 0) throw new CustomizeException(ResultCode.ERROR.getValue(), "添加失败，请稍后重试");

        return R.ok().data("courseId", eduCourse.getId());
    }

    @Override
    public R getCourseInfo(String courseId) {
        // 获取到课程基础信息
        final EduCourse eduCourse = baseMapper.selectById(courseId);


        // 获取到课程简介
        final EduCourseDescription eduCourseDescription = courseDescriptionMapper.selectById(courseId);


        // 创建封装对象
        final CourseInfoVo courseInfoVo = new CourseInfoVo();


        // 进行封装 课程信息 、课程简介
        BeanUtils.copyProperties(eduCourse, courseInfoVo);
        courseInfoVo.setDescription(eduCourseDescription.getDescription());


        return R.ok().data("courseInfoVo", courseInfoVo);
    }

    @Override
    public R updateCourseInfo(CourseInfoVo courseInfoVo) {

        // 读取要修改的课程信息
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVo, eduCourse);
        // 进行修改
        boolean flag = baseMapper.updateById(eduCourse) != 0;


        // 读取要修改的课程简介
        EduCourseDescription eduCourseDescription = new EduCourseDescription();
        courseInfoVo.setDescription(eduCourseDescription.getDescription());
        // 进行修改
        flag = flag || courseDescriptionMapper.updateById(eduCourseDescription) != 0;

        return flag ? R.ok().message("修改成功") : R.ok().message("您没有修改任何数据");
    }

    // 根据课程 id 获取到课程发布信息
    @Override
    public R getPublishCourseInfo(String id) {
        CoursePublishVo publishCourseInfo = baseMapper.getPublishCourseInfo(id);
       return publishCourseInfo == null ? R.error().message("没有查找到数据") : R.ok().data("publishCourseInfo",publishCourseInfo);

    }

    @Override
    public R PublishCourse(String id) {

        EduCourse eduCourse = baseMapper.selectById(id);

        if (eduCourse != null){
            eduCourse.setStatus("Normal"); // 课程状态 Draft未发布  Normal已发布
            baseMapper.updateById(eduCourse);
            return R.ok().message("课程发布成功");
        }else {
            return R.error().message("课程编号错误");
        }
    }

    @Override
    public List<CoursePublishVo> selectCoursePage(CourseQuery query,Page<CoursePublishVo> page) {
        return baseMapper.selectCoursePage(query,page);
    }

    @Override
    public R deleteCourse(String id) {
        return baseMapper.deleteCourseAllInfo(id)>0?R.ok():R.error().message("删除失败，请稍后重试");

    }

    @Override
    public R removeCurse(String courseId) {

        //1根据课程id删除小节
        eduVideoService.removeVideoByCourseId(courseId);
        //2根据课程id删除章节
        chapterService.removeChapterByCourseId(courseId);
        //3根据课穰d删除描述
        courseDescriptionService.removeById(courseId);
        //4根据课程id删除课程本身
        int result = baseMapper.deleteById(courseId);

        if (result == 0) { //失败返回
            throw new CustomizeException(20001, "删除失败");
        }

        return R.ok();
    }

    @Override
    public Map<String, Object> getCourseFrontList(Page<EduCourse> coursePage, CourseFrontVo vo) {
        // 创建条件查询对象
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();

        // 判断是否存在一级分类筛选
        if (!StringUtils.isNullOrEmpty(vo.getSubjectParentId()))
            wrapper.eq("subject_parent_id",vo.getSubjectParentId());

        // 判断是否存在二级分类筛选
        if (!StringUtils.isNullOrEmpty(vo.getSubjectId()))
            wrapper.eq("subject_id",vo.getSubjectId());

        // 我们的排序规则，是根据实体类中，三个排序字段中，那个不为 null 就按照那个规则进行排序

        // 如果销量不为 null 就按照销量排序
        if (!StringUtils.isNullOrEmpty(vo.getBuyCountSort()))
            wrapper.orderByDesc("buy_count");

        // 如果最新时间不为 null，就根据最新创建时间排序
        if (!StringUtils.isNullOrEmpty(vo.getGmtCreateSort()))
            wrapper.orderByDesc("gmt_create");

        // 如果价格不为 null ，就按照价格排序
        if (!StringUtils.isNullOrEmpty(vo.getPriceSort()))
            wrapper.orderByDesc("price");

        baseMapper.selectPage(coursePage,wrapper);

        List<EduCourse> records = coursePage.getRecords();
        long pages = coursePage.getPages();
        long current = coursePage.getCurrent();
        long total = coursePage.getTotal();
        long size = coursePage.getSize();
        boolean hasPrevious = coursePage.hasPrevious();//上一页
        boolean hasNext = coursePage.hasNext();//下一页

        //把分页数据获取出来，放到 map集合
        Map<String, Object> map = new HashMap<>();
        map.put("pages", pages);
        map.put("items", records);
        map.put("size", size);
        map.put("total", total);
        map.put("hasNext", hasNext);
        map.put("current", current);
        map.put("hasPrevious", hasPrevious);


        return map;
    }

    @Override
    public CourseWebVo getBaseCourseInfo(String id) {
        return baseMapper.getBaseCourseInfo(id);
    }


}
